package com.jsyl.lwbk.business.handle;

import com.jsyl.lwbk.common.utils.UrlUtil;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.util.HashMap;
import java.util.Map;


@Service
public class RestFullService {

    private RestTemplate restTemplate = new RestTemplate();

    /**
     * get 请求
     * @param url  请求路径
     * @param path
     * @param returnType 返回类型
     * @param queryParams 请求参数
     * @param headers 请求头
     * @return
     */
    public <T> T get(String url,String path,Class<T> returnType,Map<String,Object> queryParams,Map<String,String> headers){
        return get(UrlUtil.joinPath(url,path),returnType,queryParams,headers);
    }

    public <T> T get(String url,Class<T> returnType,Map<String,Object> queryParams,Map<String,String> headers){
        return getAndInjectHeaders(url,returnType,queryParams,headers,null);
    }

    public <T> T getAndInjectHeaders(String url,Class<T> returnType,Map<String,Object> queryParams,Map<String,String> headers,Map<String,String> responseHeaders){
        ResponseEntity<T> responseEntity;
        if(queryParams == null){
            queryParams = new HashMap<>();
        }
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
        for(Map.Entry<String,Object> entry : queryParams.entrySet()){
            if(entry.getValue() != null){
                builder.queryParam(entry.getKey(),entry.getValue());
            }
        }

        if(headers != null){

            HttpHeaders requestHeaders = new HttpHeaders();
            for(Map.Entry<String,String> entry : headers.entrySet()){
                if(entry.getValue() != null){
                    requestHeaders.add(entry.getKey(),entry.getValue());
                }
            }
            HttpEntity httpEntity = new HttpEntity(null,requestHeaders);


            responseEntity = restTemplate.exchange(builder.build().encode().toUri(),
                    HttpMethod.GET,httpEntity,returnType);
        }else {
            responseEntity = restTemplate.getForEntity(builder.build().encode().toUri(),returnType);
        }

        if(responseHeaders != null){
            responseHeaders.putAll(responseEntity.getHeaders().toSingleValueMap());
        }

        return responseEntity.getBody();
    }

    /**
     * post 请求
     * @param url  请求路径
     * @param path
     * @param returnType 返回类型
     * @param bodyParams 请求参数
     * @param headers 请求头
     * @return
     */
    public <T> T post(String url,String path,Class<T> returnType,Map<String,Object> bodyParams,Map<String,String> headers){
        return post(UrlUtil.joinPath(url,path),returnType,bodyParams,headers);
    }

    public <T> T post(String url,Class<T> returnType,Object bodyParams,Map<String,String> headers){
        HttpEntity requestEntity=getRequestEntity(headers,bodyParams);

        ResponseEntity<T> responseEntity = restTemplate.postForEntity(url,requestEntity,returnType);
        return responseEntity.getBody();
    }



    /**
     * post 请求
     * @param url  请求路径
     * @param path
     * @param returnType 返回类型
     * @param bodyParams 请求参数
     * @param headers 请求头
     * @return
     */
    public <T> T put(String url,String path,Class<T> returnType,Map<String,Object> bodyParams,Map<String,String> headers){
        return exchange(UrlUtil.joinPath(url,path),returnType,bodyParams,headers,HttpMethod.PUT);
    }

    public <T> T delete(String url,String path,Class<T> returnType,Map<String,Object> bodyParams,Map<String,String> headers){
        return exchange(UrlUtil.joinPath(url,path),returnType,bodyParams,headers,HttpMethod.DELETE);
    }

    /**
     * 发送/获取 服务端数据(主要用于解决发送put,delete方法无返回值问题).
     */
    public <T> T exchange(String url,Class<T> returnType,Object bodyParams,Map<String,String> headers,HttpMethod method) {
        HttpEntity requestEntity =getRequestEntity(headers,bodyParams);
        ResponseEntity<T> responseEntity = restTemplate.exchange(url, method, requestEntity, returnType);
        return responseEntity.getBody();
    }

    private HttpEntity getRequestEntity(Map<String,String> headers,Object bodyParams){
        HttpEntity requestEntity ;
        if(headers != null){
            MultiValueMap<String,String> multiValueMap = new LinkedMultiValueMap<>();
            multiValueMap.setAll(headers);
            requestEntity = new HttpEntity(bodyParams,multiValueMap);
        }else{
            requestEntity = new HttpEntity(bodyParams);
        }
        return requestEntity;
    }

    public Map<String,String> getJsonHeader(){
        Map<String,String> map = new HashMap<String,String>();
        map.put("Connection", "Keep-Alive");
        map.put("Charset", "UTF-8");
        map.put("Content-Type","application/json; charset=UTF-8");
        map.put("accept","application/json");
        return map;
    }
}
